package tasks

import (
	"fmt"
	"runtime"
	"runtime/debug"
	"sync"

	"cashew.com/cashew_api/services"
	"cashew.com/cashew_common/configs"
	"github.com/beego/beego/v2/core/logs"
	"github.com/panjf2000/ants"
)

var (
	once                         sync.Once
	cocoPushTaskPool             *ants.Pool
	cocoPushTaskChannel          chan services.CocoPushMessageReq
	balanceNoticeTaskPool        *ants.Pool
	balanceNoticeTaskChannel     chan services.ImUserAmountChangeMsgRequest
	antsPoolMaxCocoPushTask      int // 定义协程池最大协程数
	antsPoolMaxBalanceNoticeTask int // 定义协程池最大协程数
)

func init() {
	once.Do(initAntsPool)
}

func initAntsPool() {
	antsPoolMaxCocoPushTask = runtime.NumCPU()
	antsPoolMaxBalanceNoticeTask = runtime.NumCPU()
	if runtime.NumCPU() > 2 {
		// 限制最大协程数为cpu核心数的一半，防止过多的协程占用系统资源
		antsPoolMaxCocoPushTask = runtime.NumCPU() / 2
		antsPoolMaxBalanceNoticeTask = runtime.NumCPU() / 2
	}
	cocoPushTaskChannel = make(chan services.CocoPushMessageReq, configs.AntsPoolMaxCocoPushWait)
	balanceNoticeTaskChannel = make(chan services.ImUserAmountChangeMsgRequest, configs.AntsPoolMaxBalanceNoticeWait)
}

func AntsPoolStart() {
	// 启动 firebase 通知任务协程池
	startCocoPushTaskPool(cocoPushTaskChannel, func(args services.CocoPushMessageReq) {
		services.CocoPush(&args)
	})

	// 启动余额变更通知任务协程池
	startBalanceNoticeTaskPool(balanceNoticeTaskChannel, func(args services.ImUserAmountChangeMsgRequest) {
		services.ImUserAmountChangeMsg(&args)
	})
	//select {}
}
func startCocoPushTaskPool(taskChannel chan services.CocoPushMessageReq, taskFunc func(args services.CocoPushMessageReq)) {
	var err error

	cocoPushTaskPool, err = ants.NewPool(antsPoolMaxCocoPushTask, ants.WithPanicHandler(func(i interface{}) {
		logs.Error("PushTask 协程池异常: Panic: %v\\nStack: %s", i, debug.Stack())
	}))
	if err != nil {
		logs.Error("初始化协程池失败:%v", err)
		return
	}

	go func() {
		for taskArgs := range taskChannel {
			err = cocoPushTaskPool.Submit(func() {
				taskFunc(taskArgs)
			})
			if err != nil {
				logs.Error("协程池满，任务提交失败，等待协程池有空余协程: %v", err)
				// 可以添加重试逻辑或其他错误处理机制
			}
		}
	}()

	//defer cocoPushTaskPool.Release()
}

func startBalanceNoticeTaskPool(taskChannel chan services.ImUserAmountChangeMsgRequest, taskFunc func(args services.ImUserAmountChangeMsgRequest)) {
	var err error

	balanceNoticeTaskPool, err = ants.NewPool(antsPoolMaxBalanceNoticeTask, ants.WithPanicHandler(func(i interface{}) {
		logs.Error("balanceNoticeTask 协程池异常: Panic: %v\\nStack: %s", i, debug.Stack())
	}))
	if err != nil {
		logs.Error("初始化协程池失败:%v", err)
		return
	}
	go func() {
		for taskArgs := range taskChannel {
			err = balanceNoticeTaskPool.Submit(func() {
				taskFunc(taskArgs)
			})
			if err != nil {
				logs.Error("协程池满，任务提交失败，等待协程池有空余协程: %v", err)
				// 可以添加重试逻辑或其他错误处理机制
			}
		}
	}()

	//defer balanceNoticeTaskPool.Release()
}

// 提交余额变更通知任务
func SubmitBalanceChangeNoticeTask(taskArgs *services.ImUserAmountChangeMsgRequest) error {
	select {
	case balanceNoticeTaskChannel <- *taskArgs:
		logs.Info("提交余额变更通知任务测试方法成功 userId:%v", taskArgs.UserId)
	default:
		logs.Error("任务通道已满，无法提交任务 userId:%v", taskArgs.UserId)
		return fmt.Errorf("任务通道已满，无法提交任务")
	}
	return nil
}

// 提交安卓推送通知任务
func SubmitCocoPushTask(taskArgs *services.CocoPushMessageReq) error {
	select {
	case cocoPushTaskChannel <- *taskArgs:
		logs.Info("提交 coco 推送通知任务成功 taskArgs:%+v", taskArgs)
	default:
		logs.Error("提交 coco 推送通知任务任务通道已满，无法提交任务 taskArgs:%+v", taskArgs)
		return fmt.Errorf("任务通道已满，无法提交任务")
	}
	return nil
}

// 统计协程池状态
func AntsPoolStatus() map[string]interface{} {
	res := map[string]interface{}{
		"cocoPushPool": map[string]interface{}{
			"poolCapNum":     cocoPushTaskPool.Cap(),
			"poolFreeNum":    cocoPushTaskPool.Free(),
			"poolRunningNum": cocoPushTaskPool.Running(),
			"channelLen":     len(cocoPushTaskChannel),
			"channelCap":     cap(cocoPushTaskChannel),
		},
		"balanceChangeNotic": map[string]interface{}{
			"poolCapNum":     balanceNoticeTaskPool.Cap(),
			"poolFreeNum":    balanceNoticeTaskPool.Free(),
			"poolRunningNum": balanceNoticeTaskPool.Running(),
			"channelLen":     len(balanceNoticeTaskChannel),
			"channelCap":     cap(balanceNoticeTaskChannel),
		},
	}

	return res
}
